home *** CD-ROM | disk | FTP | other *** search
/ The Complete Utilities To…ka 501 Killer Utilities! / 501 Killer Utilities! (Macworld July 1995).cdr / Programming / OutOfPhase1.1 Source / OutOfPhase Folder / WaveTableOscControl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-04  |  55.5 KB  |  1,507 lines  |  [TEXT/KAHL]

  1. /* WaveTableOscControl.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "WaveTableOscControl.h"
  31. #include "FastFixedPoint.h"
  32. #include "Memory.h"
  33. #include "EnvelopeState.h"
  34. #include "SampleConsts.h"
  35. #include "LFOGenerator.h"
  36. #include "Multisampler.h"
  37. #include "OscillatorSpecifier.h"
  38. #include "Envelope.h"
  39. #include "LFOListSpecifier.h"
  40. #include "64BitMath.h"
  41. #include "ErrorDaemon.h"
  42.  
  43.  
  44. /* prototypes for fast playback routines */
  45. static void                        Wave_Mono_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
  46.                                                 long SampleCount, largefixedsigned* RawBuffer);
  47. static void                        Wave_Stereo_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
  48.                                                 long SampleCount, largefixedsigned* RawBuffer);
  49. static void                        Wave_Mono_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
  50.                                                 long SampleCount, largefixedsigned* RawBuffer);
  51. static void                        Wave_Stereo_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
  52.                                                 long SampleCount, largefixedsigned* RawBuffer);
  53.  
  54. static void                        Wave_Mono_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
  55.                                                 long SampleCount, largefixedsigned* RawBuffer);
  56. static void                        Wave_Stereo_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
  57.                                                 long SampleCount, largefixedsigned* RawBuffer);
  58. static void                        Wave_Mono_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
  59.                                                 long SampleCount, largefixedsigned* RawBuffer);
  60. static void                        Wave_Stereo_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
  61.                                                 long SampleCount, largefixedsigned* RawBuffer);
  62.  
  63. static void                        Wave_Mono_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
  64.                                                 long SampleCount, largefixedsigned* RawBuffer);
  65. static void                        Wave_Stereo_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
  66.                                                 long SampleCount, largefixedsigned* RawBuffer);
  67. static void                        Wave_Mono_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
  68.                                                 long SampleCount, largefixedsigned* RawBuffer);
  69. static void                        Wave_Stereo_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
  70.                                                 long SampleCount, largefixedsigned* RawBuffer);
  71.  
  72. static void                        Wave_NoOutput(WaveTableStateRec* State,
  73.                                                 long SampleCount, largefixedsigned* RawBuffer);
  74.  
  75.  
  76. /* wave table oscillator template information record */
  77. struct WaveTableTemplateRec
  78.     {
  79.         /* source information for the wave table */
  80.         MultiSampleRec*                WaveTableSourceSelector;
  81.  
  82.         /* sampling rate for final output */
  83.         long                                    FinalOutputSamplingRate;
  84.         /* number of envelope updates per second */
  85.         float                                    EnvelopeTicksPerSecond;
  86.  
  87.         /* values for scaling the frequency of something.  if we were really serious about */
  88.         /* this, we'd traverse all of the oscillators with integral multiples or harmonic */
  89.         /* fractions of the pitch & set their differentials to the same precision as the */
  90.         /* worst oscillator so that they would all stay in sync as time progressed. */
  91.         float                                    FrequencyMultiplier;
  92.         /* this is added after the frequency multiplier is applied */
  93.         float                                    FrequencyAdder;
  94.  
  95.         /* stereo status */
  96.         NumChannelsType                StereoPlayback;
  97.         /* time interpolation flag */
  98.         MyBoolean                            InterpolateThroughTime;
  99.         /* inter-wave interpolation flag */
  100.         MyBoolean                            InterpolateAcrossWaves;
  101.  
  102.         /* envelope templates */
  103.         EnvelopeRec*                    LoudnessEnvelopeTemplate;
  104.         LFOListSpecRec*                LoudnessLFOTemplate;
  105.         EnvelopeRec*                    IndexEnvelopeTemplate;
  106.         LFOListSpecRec*                IndexLFOTemplate;
  107.  
  108.         /* miscellaneous control parameters */
  109.         float                                    StereoBias;
  110.         float                                    TimeDisplacement;
  111.         float                                    OverallOscillatorLoudness;
  112.  
  113.         /* error logging facility */
  114.         ErrorDaemonRec*                ErrorDaemon;
  115.  
  116.         /* template for the pitch displacement LFO */
  117.         LFOListSpecRec*                PitchLFOTemplate;
  118.  
  119.         /* link for list control */
  120.         WaveTableTemplateRec*    Next;
  121.     };
  122.  
  123.  
  124. /* wave table oscillator state record */
  125. struct WaveTableStateRec
  126.     {
  127.         /* current sample position into the wave table */
  128.         LongLongRec                        WaveTableSamplePosition; /* 32-bit fixed point */
  129.         /* current increment value for the wave table sample position */
  130.         LongLongRec                        WaveTableSamplePositionDifferential; /* 32-bit fixed point */
  131.  
  132.         /* envelope tick countdown for pre-start time */
  133.         long                                    PreStartCountdown;
  134.  
  135.         /* function for generating a bunch of samples from the wave table */
  136.         void                                    (*WaveTableGenSamples)(WaveTableStateRec* State,
  137.                                                         long SampleCount, largefixedsigned* RawBuffer);
  138.  
  139.         /* number of frames per table */
  140.         long                                    FramesPerTable;
  141.         /* number of tables */
  142.         long                                    NumberOfTables;
  143.         /* raw wave table data array */
  144.         void**                                WaveTableMatrix;
  145.         /* number of bits in the data for the table */
  146.         NumBitsType                        TableNumBits;
  147.  
  148.         /* current index into table of waves.  0 = lowest wave table, NumberOfTables = highest */
  149.         FastFixedType                    WaveTableIndex;
  150.         /* envelope controlling wave table index */
  151.         EvalEnvelopeRec*            WaveTableIndexEnvelope;
  152.         /* LFO generators modifying the output of the index envelope generator */
  153.         LFOGenRec*                        IndexLFOGenerator;
  154.  
  155.         /* NOTE:  either OverallLoudness or Left/RightLoudness are used, but not both */
  156.         /* current overall loudness for oscillator */
  157.         FastFixedType                    OverallLoudness; /* 15-bit fixed point, 0..1 */
  158.         /* left channel loudness */
  159.         FastFixedType                    LeftLoudness; /* 15-bit fixed point, 0..1 */
  160.         /* right channel loudness */
  161.         FastFixedType                    RightLoudness; /* 15-bit fixed point, 0..1 */
  162.         /* panning position for splitting envelope generator into stereo channels */
  163.         /* 0 = left channel, 0.5 = middle, 1 = right channel */
  164.         FastFixedType                    Panning; /* 15-bit fixed point, -1..1 */
  165.         /* envelope that is generating the loudness information */
  166.         EvalEnvelopeRec*            WaveTableLoudnessEnvelope;
  167.         /* LFO generators modifying the output of the loudness envelope generator */
  168.         LFOGenRec*                        LoudnessLFOGenerator;
  169.  
  170.         /* this flag is True if the wave table data was defined at the specified pitch */
  171.         /* (and the wave table array is thus valid) or False if there is no wave table */
  172.         /* at this pitch (and the array is invalid) */
  173.         MyBoolean                            WaveTableWasDefined;
  174.  
  175.         /* this field contains the overall volume scaling for everything so that we */
  176.         /* can treat the envelopes as always going between 0 and 1. */
  177.         float                                    NoteLoudnessScaling;
  178.  
  179.         /* this calculates the differential values for periodic pitch displacements */
  180.         LFOGenRec*                        PitchLFO;
  181.         /* pitch lfo startup counter; negative = expired */
  182.         long                                    PitchLFOStartCountdown;
  183.  
  184.         /* static information for the wave table */
  185.         WaveTableTemplateRec    Template; /* a copy of the data */
  186.  
  187.         /* link for list control */
  188.         WaveTableStateRec*        Next;
  189.     };
  190.  
  191.  
  192.  
  193.  
  194. static WaveTableTemplateRec*        WaveTableTemplateFreeList = NIL;
  195. static WaveTableStateRec*                WaveTableStateFreeList = NIL;
  196.  
  197.  
  198. /* get rid of all cached memory for state or template records */
  199. void                                    FlushWaveTableOscControl(void)
  200.     {
  201.         while (WaveTableTemplateFreeList != NIL)
  202.             {
  203.                 WaveTableTemplateRec*        Temp;
  204.  
  205.                 Temp = WaveTableTemplateFreeList;
  206.                 WaveTableTemplateFreeList = WaveTableTemplateFreeList->Next;
  207.                 ReleasePtr((char*)Temp);
  208.             }
  209.  
  210.         while (WaveTableStateFreeList != NIL)
  211.             {
  212.                 WaveTableStateRec*        Temp;
  213.  
  214.                 Temp = WaveTableStateFreeList;
  215.                 WaveTableStateFreeList = WaveTableStateFreeList->Next;
  216.                 ReleasePtr((char*)Temp);
  217.             }
  218.     }
  219.  
  220.  
  221. #if DEBUG
  222. static void                        CheckValidWaveTableTemplate(WaveTableTemplateRec* Object)
  223.     {
  224.         WaveTableTemplateRec*    Scan;
  225.  
  226.         Scan = WaveTableTemplateFreeList;
  227.         while (Scan != NIL)
  228.             {
  229.                 if (Scan == Object)
  230.                     {
  231.                         PRERR(ForceAbort,"CheckValidWaveTableTemplate:  template is on free list");
  232.                     }
  233.                 Scan = Scan->Next;
  234.             }
  235.     }
  236. #else
  237. #define CheckValidWaveTableTemplate(x) ((void)0)
  238. #endif
  239.  
  240.  
  241. #if DEBUG
  242. static void                        CheckValidWaveTableState(WaveTableStateRec* Object)
  243.     {
  244.         WaveTableStateRec*        Scan;
  245.  
  246.         Scan = WaveTableStateFreeList;
  247.         while (Scan != NIL)
  248.             {
  249.                 if (Scan == Object)
  250.                     {
  251.                         PRERR(ForceAbort,"CheckValidWaveTableState:  state is on free list");
  252.                     }
  253.                 Scan = Scan->Next;
  254.             }
  255.     }
  256. #else
  257. #define CheckValidWaveTableState(x) ((void)0)
  258. #endif
  259.  
  260.  
  261. /* perform one envelope update cycle */
  262. void                                    UpdateWaveTableEnvelopes(WaveTableStateRec* State)
  263.     {
  264.         FastFixedType                Temp;
  265.  
  266.         CheckPtrExistence(State);
  267.         CheckValidWaveTableState(State);
  268.  
  269.         /* this is for the benefit of resampling only -- envelope generators do their */
  270.         /* own pre-origin sequencing */
  271.         if (State->PreStartCountdown > 0)
  272.             {
  273.                 State->PreStartCountdown -= 1;
  274.             }
  275.  
  276.         Temp = (State->NumberOfTables - 1) * LFOGenUpdateCycle(State->IndexLFOGenerator,
  277.             EnvelopeUpdate(State->WaveTableIndexEnvelope));
  278.         if (Temp < 0)
  279.             {
  280.                 Temp = 0;
  281.             }
  282.         else if (Temp > Int2FastFixed(State->NumberOfTables - 1))
  283.             {
  284.                 Temp = Int2FastFixed(State->NumberOfTables - 1);
  285.             }
  286.         State->WaveTableIndex = Temp;
  287.  
  288.         Temp = State->NoteLoudnessScaling * LFOGenUpdateCycle(State->LoudnessLFOGenerator,
  289.             EnvelopeUpdate(State->WaveTableLoudnessEnvelope));
  290.         /* fast fixed has a very narrow range, so overflow can't be permitted: */
  291.         /* 15x15->30 bits, with 2 extra bits; we use one for sign and the other */
  292.         /* to permit the representation of 1 and -1. */
  293.         if (State->Template.StereoPlayback == eSampleMono)
  294.             {
  295.                 if (Temp < - Int2FastFixed(1))
  296.                     {
  297.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  298.                             - FastFixed2Float(Temp));
  299.                         Temp = - Int2FastFixed(1);
  300.                     }
  301.                 else if (Temp > Int2FastFixed(1))
  302.                     {
  303.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  304.                             FastFixed2Float(Temp));
  305.                         Temp = Int2FastFixed(1);
  306.                     }
  307.                 State->OverallLoudness = Temp;
  308.             }
  309.          else
  310.             {
  311.                 FastFixedType                LeftVolumeScaling;
  312.                 FastFixedType                RightVolumeScaling;
  313.                 FastFixedType                MaxVolScaling;
  314.                 FastFixedType                MaxTemp;
  315.  
  316.                 LeftVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
  317.                     Int2FastFixed(1) - State->Panning);
  318.                 RightVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
  319.                     Int2FastFixed(1) + State->Panning);
  320.  
  321.                 if (((LeftVolumeScaling >= 0) ? LeftVolumeScaling : (- LeftVolumeScaling))
  322.                     > ((RightVolumeScaling >= 0) ? RightVolumeScaling : (- RightVolumeScaling)))
  323.                     {
  324.                         MaxVolScaling = ((LeftVolumeScaling >= 0)
  325.                             ? LeftVolumeScaling : (- LeftVolumeScaling));
  326.                     }
  327.                  else
  328.                     {
  329.                         MaxVolScaling = ((RightVolumeScaling >= 0)
  330.                             ? RightVolumeScaling : (- RightVolumeScaling));
  331.                     }
  332.                 MaxTemp = Double2FastFixed((float)1 / FastFixed2Float(MaxVolScaling));
  333.                 if (Temp < - MaxTemp)
  334.                     {
  335.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  336.                             - FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
  337.                         Temp = - MaxTemp;
  338.                     }
  339.                 else if (Temp > MaxTemp)
  340.                     {
  341.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  342.                             FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
  343.                         Temp = MaxTemp;
  344.                     }
  345.  
  346.                 State->LeftLoudness = FastFixedTimesFastFixedToFastFixed(
  347.                     LeftVolumeScaling,Temp);
  348.                 State->RightLoudness = FastFixedTimesFastFixedToFastFixed(
  349.                     RightVolumeScaling,Temp);
  350.             }
  351.     }
  352.  
  353.  
  354. /* dispose of the wave table state record */
  355. void                                    DisposeWaveTableState(WaveTableStateRec* State)
  356.     {
  357.         CheckPtrExistence(State);
  358.         CheckValidWaveTableState(State);
  359.  
  360.         DisposeEnvelopeStateRecord(State->WaveTableIndexEnvelope);
  361.         DisposeLFOGenerator(State->IndexLFOGenerator);
  362.         DisposeEnvelopeStateRecord(State->WaveTableLoudnessEnvelope);
  363.         DisposeLFOGenerator(State->LoudnessLFOGenerator);
  364.         DisposeLFOGenerator(State->PitchLFO);
  365.  
  366.         State->Next = WaveTableStateFreeList;
  367.         WaveTableStateFreeList = State;
  368.     }
  369.  
  370.  
  371. /* dispose of the wave table information template */
  372. void                                    DisposeWaveTableTemplate(WaveTableTemplateRec* Template)
  373.     {
  374.         CheckPtrExistence(Template);
  375.         CheckValidWaveTableTemplate(Template);
  376.  
  377.         DisposeMultisample(Template->WaveTableSourceSelector);
  378.  
  379.         Template->Next = WaveTableTemplateFreeList;
  380.         WaveTableTemplateFreeList = Template;
  381.     }
  382.  
  383.  
  384. /* create a new wave table template */
  385. WaveTableTemplateRec*    NewWaveTableTemplate(struct OscillatorRec* Oscillator,
  386.                                                 float EnvelopeTicksPerSecond, long SamplingRate,
  387.                                                 MyBoolean Stereo, MyBoolean TimeInterp, MyBoolean WaveInterp,
  388.                                                 ErrorDaemonRec* ErrorDaemon)
  389.     {
  390.         WaveTableTemplateRec*    Template;
  391.  
  392.         CheckPtrExistence(ErrorDaemon);
  393.         CheckPtrExistence(Oscillator);
  394.         ERROR(OscillatorGetWhatKindItIs(Oscillator) != eOscillatorWaveTable,PRERR(ForceAbort,
  395.             "NewWaveTableTemplate:  oscillator is not a wave table"));
  396.  
  397.         if (WaveTableTemplateFreeList != NIL)
  398.             {
  399.                 Template = WaveTableTemplateFreeList;
  400.                 WaveTableTemplateFreeList = WaveTableTemplateFreeList->Next;
  401.             }
  402.          else
  403.             {
  404.                 Template = (WaveTableTemplateRec*)AllocPtrCanFail(sizeof(WaveTableTemplateRec),
  405.                     "WaveTableTemplateRec");
  406.                 if (Template == NIL)
  407.                     {
  408.                         return NIL;
  409.                     }
  410.             }
  411.         EXECUTE(Template->Next = (WaveTableTemplateRec*)0x81818181;)
  412.  
  413.         Template->WaveTableSourceSelector = NewMultisampleWaveTable(
  414.             OscillatorGetSampleIntervalList(Oscillator));
  415.         if (Template->WaveTableSourceSelector == NIL)
  416.             {
  417.              FailurePoint1:
  418.                 Template->Next = WaveTableTemplateFreeList;
  419.                 WaveTableTemplateFreeList = Template;
  420.                 return NIL;
  421.             }
  422.  
  423.         Template->FinalOutputSamplingRate = SamplingRate;
  424.         Template->EnvelopeTicksPerSecond = EnvelopeTicksPerSecond;
  425.         Template->OverallOscillatorLoudness = OscillatorGetOutputLoudness(Oscillator);
  426.  
  427.         /* it might be better to handle divisor and multiplier separately -- we would */
  428.         /* want to do that if we were trying to guarantee that all harmonic */
  429.         /* oscillators ran in lock-step */
  430.         Template->FrequencyMultiplier = OscillatorGetFrequencyMultiplier(Oscillator)
  431.             / OscillatorGetFrequencyDivisor(Oscillator);
  432.         Template->FrequencyAdder = OscillatorGetFrequencyAdder(Oscillator);
  433.  
  434.         Template->StereoBias = OscillatorGetStereoBias(Oscillator);
  435.         Template->TimeDisplacement = OscillatorGetTimeDisplacement(Oscillator);
  436.  
  437.         if (Stereo)
  438.             {
  439.                 Template->StereoPlayback = eSampleStereo;
  440.             }
  441.          else
  442.             {
  443.                 Template->StereoPlayback = eSampleMono;
  444.             }
  445.         Template->InterpolateThroughTime = TimeInterp;
  446.         Template->InterpolateAcrossWaves = WaveInterp;
  447.  
  448.         /* these are just references */
  449.         Template->LoudnessEnvelopeTemplate = OscillatorGetLoudnessEnvelope(Oscillator);
  450.         Template->LoudnessLFOTemplate = OscillatorGetLoudnessLFOList(Oscillator);
  451.         Template->IndexEnvelopeTemplate = OscillatorGetExcitationEnvelope(Oscillator);
  452.         Template->IndexLFOTemplate = OscillatorGetExcitationLFOList(Oscillator);
  453.  
  454.         /* more references */
  455.         Template->ErrorDaemon = ErrorDaemon;
  456.         Template->PitchLFOTemplate = GetOscillatorFrequencyLFOList(Oscillator);
  457.  
  458.         return Template;
  459.     }
  460.  
  461.  
  462. /* create a new wave table state object. */
  463. WaveTableStateRec*        NewWaveTableState(WaveTableTemplateRec* Template,
  464.                                                 float FreqForMultisampling, float Accent1, float Accent2,
  465.                                                 float Accent3, float Accent4, float Loudness, float HurryUp,
  466.                                                 long* PreOriginTimeOut, float StereoPosition,
  467.                                                 float InitialFrequency, float PitchDisplacementDepthLimit,
  468.                                                 float PitchDisplacementRateLimit,
  469.                                                 long PitchDisplacementStartPoint)
  470.     {
  471.         WaveTableStateRec*    State;
  472.         long                                MaxPreOrigin;
  473.         long                                OnePreOrigin;
  474.  
  475.         CheckPtrExistence(Template);
  476.         CheckValidWaveTableTemplate(Template);
  477.  
  478.         if (WaveTableStateFreeList != NIL)
  479.             {
  480.                 State = WaveTableStateFreeList;
  481.                 WaveTableStateFreeList = WaveTableStateFreeList->Next;
  482.             }
  483.          else
  484.             {
  485.                 State = (WaveTableStateRec*)AllocPtrCanFail(sizeof(WaveTableStateRec),
  486.                     "WaveTableStateRec");
  487.                 if (State == NIL)
  488.                     {
  489.                      FailurePoint1:
  490.                         return NIL;
  491.                     }
  492.             }
  493.         EXECUTE(State->Next = (WaveTableStateRec*)0x81818181;)
  494.  
  495.         State->Template = *Template;
  496.  
  497.         MaxPreOrigin = 0;
  498.  
  499.         Double2LongLong(0,&(State->WaveTableSamplePosition));
  500.         /* State->WaveTableSamplePositionDifferential specified in separate call */
  501.  
  502.         State->NoteLoudnessScaling = Loudness * Template->OverallOscillatorLoudness;
  503.  
  504.         State->WaveTableWasDefined = GetMultisampleReferenceWaveTable(
  505.             Template->WaveTableSourceSelector,FreqForMultisampling,&(State->WaveTableMatrix),
  506.             &(State->FramesPerTable),&(State->NumberOfTables),&(State->TableNumBits));
  507.  
  508.         /* State->WaveTableWasDefined: */
  509.         /*   if there is no wave table defined for the current pitch, then we don't */
  510.         /*   bother generating any data */
  511.         /* State->FramesPerTable > 0: */
  512.         /*   if the wave table is empty, then we don't do any work (and we must not, */
  513.         /*   since array accesses would cause a crash) */
  514.         if (State->WaveTableWasDefined && (State->FramesPerTable > 0))
  515.             {
  516.                 if (Template->StereoPlayback == eSampleStereo)
  517.                     {
  518.                         if (State->TableNumBits == eSample16bit)
  519.                             {
  520.                                 if (Template->InterpolateAcrossWaves)
  521.                                     {
  522.                                         State->WaveTableGenSamples = &Wave_Stereo_16BitIn_YesTime_YesWave;
  523.                                     }
  524.                                 else if (Template->InterpolateThroughTime)
  525.                                     {
  526.                                         State->WaveTableGenSamples = &Wave_Stereo_16BitIn_YesTime_NoWave;
  527.                                     }
  528.                                 else
  529.                                     {
  530.                                         State->WaveTableGenSamples = &Wave_Stereo_16BitIn_NoTime_NoWave;
  531.                                     }
  532.                             }
  533.                          else
  534.                             {
  535.                                 if (Template->InterpolateAcrossWaves)
  536.                                     {
  537.                                         State->WaveTableGenSamples = &Wave_Stereo_8BitIn_YesTime_YesWave;
  538.                                     }
  539.                                 else if (Template->InterpolateThroughTime)
  540.                                     {
  541.                                         State->WaveTableGenSamples = &Wave_Stereo_8BitIn_YesTime_NoWave;
  542.                                     }
  543.                                 else
  544.                                     {
  545.                                         State->WaveTableGenSamples = &Wave_Stereo_8BitIn_NoTime_NoWave;
  546.                                     }
  547.                             }
  548.                     }
  549.                  else
  550.                     {
  551.                         if (State->TableNumBits == eSample16bit)
  552.                             {
  553.                                 if (Template->InterpolateAcrossWaves)
  554.                                     {
  555.                                         State->WaveTableGenSamples = &Wave_Mono_16BitIn_YesTime_YesWave;
  556.                                     }
  557.                                 else if (Template->InterpolateThroughTime)
  558.                                     {
  559.                                         State->WaveTableGenSamples = &Wave_Mono_16BitIn_YesTime_NoWave;
  560.                                     }
  561.                                 else
  562.                                     {
  563.                                         State->WaveTableGenSamples = &Wave_Mono_16BitIn_NoTime_NoWave;
  564.                                     }
  565.                             }
  566.                          else
  567.                             {
  568.                                 if (Template->InterpolateAcrossWaves)
  569.                                     {
  570.                                         State->WaveTableGenSamples = &Wave_Mono_8BitIn_YesTime_YesWave;
  571.                                     }
  572.                                 else if (Template->InterpolateThroughTime)
  573.                                     {
  574.                                         State->WaveTableGenSamples = &Wave_Mono_8BitIn_YesTime_NoWave;
  575.                                     }
  576.                                 else
  577.                                     {
  578.                                         State->WaveTableGenSamples = &Wave_Mono_8BitIn_NoTime_NoWave;
  579.                                     }
  580.                             }
  581.                     }
  582.             }
  583.          else
  584.             {
  585.                 State->WaveTableGenSamples = &Wave_NoOutput;
  586.             }
  587.  
  588.         State->PreStartCountdown = Template->TimeDisplacement
  589.             * Template->EnvelopeTicksPerSecond + 0.5;
  590.         if (- State->PreStartCountdown > MaxPreOrigin)
  591.             {
  592.                 MaxPreOrigin = - State->PreStartCountdown;
  593.             }
  594.  
  595.         /* State->WaveTableIndex determined by envelope update */
  596.         State->WaveTableIndexEnvelope = NewEnvelopeStateRecord(
  597.             Template->IndexEnvelopeTemplate,Accent1,Accent2,Accent3,Accent4,InitialFrequency,
  598.             1,HurryUp,Template->EnvelopeTicksPerSecond,&OnePreOrigin);
  599.         if (State->WaveTableIndexEnvelope == NIL)
  600.             {
  601.              FailurePoint2:
  602.                 State->Next = WaveTableStateFreeList;
  603.                 WaveTableStateFreeList = State;
  604.                 goto FailurePoint1;
  605.             }
  606.         if (OnePreOrigin > MaxPreOrigin)
  607.             {
  608.                 MaxPreOrigin = OnePreOrigin;
  609.             }
  610.         State->IndexLFOGenerator = NewLFOGenerator(Template->IndexLFOTemplate,
  611.             &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
  612.             Template->EnvelopeTicksPerSecond,1,1,FreqForMultisampling);
  613.         if (State->IndexLFOGenerator == NIL)
  614.             {
  615.              FailurePoint3:
  616.                 DisposeEnvelopeStateRecord(State->WaveTableIndexEnvelope);
  617.                 goto FailurePoint2;
  618.             }
  619.         if (OnePreOrigin > MaxPreOrigin)
  620.             {
  621.                 MaxPreOrigin = OnePreOrigin;
  622.             }
  623.  
  624.         /* State->OverallLoudness, State->LeftLoudness, State->RightLoudness */
  625.         /* are determined by the envelope update */
  626.         StereoPosition += Template->StereoBias;
  627.         if (StereoPosition < -1)
  628.             {
  629.                 StereoPosition = -1;
  630.             }
  631.         else if (StereoPosition > 1)
  632.             {
  633.                 StereoPosition = 1;
  634.             }
  635.         State->Panning = Double2FastFixed(StereoPosition);
  636.         State->WaveTableLoudnessEnvelope = NewEnvelopeStateRecord(
  637.             Template->LoudnessEnvelopeTemplate,Accent1,Accent2,Accent3,Accent4,
  638.             InitialFrequency,1,HurryUp,Template->EnvelopeTicksPerSecond,&OnePreOrigin);
  639.         if (State->WaveTableLoudnessEnvelope == NIL)
  640.             {
  641.              FailurePoint4:
  642.                 DisposeLFOGenerator(State->IndexLFOGenerator);
  643.                 goto FailurePoint3;
  644.             }
  645.         if (OnePreOrigin > MaxPreOrigin)
  646.             {
  647.                 MaxPreOrigin = OnePreOrigin;
  648.             }
  649.         State->LoudnessLFOGenerator = NewLFOGenerator(Template->LoudnessLFOTemplate,
  650.             &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
  651.             Template->EnvelopeTicksPerSecond,1,1,FreqForMultisampling);
  652.         if (State->LoudnessLFOGenerator == NIL)
  653.             {
  654.              FailurePoint5:
  655.                 DisposeEnvelopeStateRecord(State->WaveTableLoudnessEnvelope);
  656.                 goto FailurePoint4;
  657.             }
  658.         if (OnePreOrigin > MaxPreOrigin)
  659.             {
  660.                 MaxPreOrigin = OnePreOrigin;
  661.             }
  662.         State->PitchLFO = NewLFOGenerator(Template->PitchLFOTemplate,
  663.             &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
  664.             Template->EnvelopeTicksPerSecond,PitchDisplacementDepthLimit,
  665.             PitchDisplacementRateLimit,FreqForMultisampling);
  666.         if (State->PitchLFO == NIL)
  667.             {
  668.              FailurePoint6:
  669.                 DisposeLFOGenerator(State->LoudnessLFOGenerator);
  670.                 goto FailurePoint5;
  671.             }
  672.         if (OnePreOrigin > MaxPreOrigin)
  673.             {
  674.                 MaxPreOrigin = OnePreOrigin;
  675.             }
  676.         State->PitchLFOStartCountdown = PitchDisplacementStartPoint;
  677.  
  678.         *PreOriginTimeOut = MaxPreOrigin;
  679.         return State;
  680.     }
  681.  
  682.  
  683. /* fix up pre-origin time for the wave table state object */
  684. void                                    FixUpWaveTableStatePreOrigin(WaveTableStateRec* State,
  685.                                                 long ActualPreOrigin)
  686.     {
  687.         CheckPtrExistence(State);
  688.         CheckValidWaveTableState(State);
  689.  
  690.         EnvelopeStateFixUpInitialDelay(State->WaveTableIndexEnvelope,ActualPreOrigin);
  691.         EnvelopeStateFixUpInitialDelay(State->WaveTableLoudnessEnvelope,ActualPreOrigin);
  692.         LFOGeneratorFixEnvelopeOrigins(State->IndexLFOGenerator,ActualPreOrigin);
  693.         LFOGeneratorFixEnvelopeOrigins(State->LoudnessLFOGenerator,ActualPreOrigin);
  694.         LFOGeneratorFixEnvelopeOrigins(State->PitchLFO,ActualPreOrigin);
  695.  
  696.         State->PreStartCountdown += ActualPreOrigin;
  697.     }
  698.  
  699.  
  700. /* set a new frequency for a wave table state object.  used for portamento */
  701. /* and modulation of frequency (vibrato) */
  702. void                                    WaveTableStateNewFrequency(WaveTableStateRec* State,
  703.                                                 float NewFrequencyHertz)
  704.     {
  705.         double                            Differential;
  706.  
  707.         CheckPtrExistence(State);
  708.         CheckValidWaveTableState(State);
  709.         if (State->PitchLFOStartCountdown > 0)
  710.             {
  711.                 State->PitchLFOStartCountdown -= 1;
  712.             }
  713.          else
  714.             {
  715.                 /* do some pitch stuff */
  716.                 NewFrequencyHertz = FastFixed2Float(LFOGenUpdateCycle(State->PitchLFO,
  717.                     Double2FastFixed(NewFrequencyHertz)));
  718.             }
  719.         Differential = (NewFrequencyHertz * State->Template.FrequencyMultiplier
  720.             + State->Template.FrequencyAdder) / State->Template.FinalOutputSamplingRate
  721.             * State->FramesPerTable;
  722.         Double2LongLong(Differential,&(State->WaveTableSamplePositionDifferential));
  723.     }
  724.  
  725.  
  726. /* send a key-up signal to one of the oscillators */
  727. void                                    WaveTableKeyUpSustain1(WaveTableStateRec* State)
  728.     {
  729.         CheckPtrExistence(State);
  730.         CheckValidWaveTableState(State);
  731.         LFOGeneratorKeyUpSustain1(State->IndexLFOGenerator);
  732.         LFOGeneratorKeyUpSustain1(State->LoudnessLFOGenerator);
  733.         EnvelopeKeyUpSustain1(State->WaveTableIndexEnvelope);
  734.         EnvelopeKeyUpSustain1(State->WaveTableLoudnessEnvelope);
  735.         LFOGeneratorKeyUpSustain1(State->PitchLFO);
  736.     }
  737.  
  738.  
  739. /* send a key-up signal to one of the oscillators */
  740. void                                    WaveTableKeyUpSustain2(WaveTableStateRec* State)
  741.     {
  742.         CheckPtrExistence(State);
  743.         CheckValidWaveTableState(State);
  744.         LFOGeneratorKeyUpSustain2(State->IndexLFOGenerator);
  745.         LFOGeneratorKeyUpSustain2(State->LoudnessLFOGenerator);
  746.         EnvelopeKeyUpSustain2(State->WaveTableIndexEnvelope);
  747.         EnvelopeKeyUpSustain2(State->WaveTableLoudnessEnvelope);
  748.         LFOGeneratorKeyUpSustain2(State->PitchLFO);
  749.     }
  750.  
  751.  
  752. /* send a key-up signal to one of the oscillators */
  753. void                                    WaveTableKeyUpSustain3(WaveTableStateRec* State)
  754.     {
  755.         CheckPtrExistence(State);
  756.         CheckValidWaveTableState(State);
  757.         LFOGeneratorKeyUpSustain3(State->IndexLFOGenerator);
  758.         LFOGeneratorKeyUpSustain3(State->LoudnessLFOGenerator);
  759.         EnvelopeKeyUpSustain3(State->WaveTableIndexEnvelope);
  760.         EnvelopeKeyUpSustain3(State->WaveTableLoudnessEnvelope);
  761.         LFOGeneratorKeyUpSustain3(State->PitchLFO);
  762.     }
  763.  
  764.  
  765. /* restart a wave table oscillator.  this is used for tie continuations */
  766. void                                    RestartWaveTableState(WaveTableStateRec* State,
  767.                                                 float NewFreqMultisampling, float NewAccent1, float NewAccent2,
  768.                                                 float NewAccent3, float NewAccent4, float NewLoudness,
  769.                                                 float NewHurryUp, MyBoolean RetriggerEnvelopes,
  770.                                                 float NewStereoPosition, float NewInitialFrequency,
  771.                                                 float PitchDisplacementDepthLimit,
  772.                                                 float PitchDisplacementRateLimit,
  773.                                                 long PitchDisplacementStartPoint)
  774.     {
  775.         CheckPtrExistence(State);
  776.         CheckValidWaveTableState(State);
  777.  
  778.         NewStereoPosition += State->Template.StereoBias;
  779.         if (NewStereoPosition < -1)
  780.             {
  781.                 NewStereoPosition = -1;
  782.             }
  783.         else if (NewStereoPosition > 1)
  784.             {
  785.                 NewStereoPosition = 1;
  786.             }
  787.         State->Panning = Double2FastFixed(NewStereoPosition);
  788.  
  789.         State->NoteLoudnessScaling = NewLoudness * State->Template.OverallOscillatorLoudness;
  790.  
  791.         EnvelopeRetriggerFromOrigin(State->WaveTableIndexEnvelope,NewAccent1,NewAccent2,
  792.             NewAccent3,NewAccent4,NewInitialFrequency,1,NewHurryUp,
  793.             State->Template.EnvelopeTicksPerSecond,RetriggerEnvelopes);
  794.         EnvelopeRetriggerFromOrigin(State->WaveTableLoudnessEnvelope,NewAccent1,
  795.             NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,1,NewHurryUp,
  796.             State->Template.EnvelopeTicksPerSecond,RetriggerEnvelopes);
  797.         LFOGeneratorRetriggerFromOrigin(State->IndexLFOGenerator,NewAccent1,NewAccent2,
  798.             NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,1,1,RetriggerEnvelopes);
  799.         LFOGeneratorRetriggerFromOrigin(State->LoudnessLFOGenerator,NewAccent1,
  800.             NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,1,1,
  801.             RetriggerEnvelopes);
  802.         LFOGeneratorRetriggerFromOrigin(State->PitchLFO,NewAccent1,
  803.             NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,
  804.             PitchDisplacementDepthLimit,PitchDisplacementRateLimit,
  805.             RetriggerEnvelopes);
  806.         if (RetriggerEnvelopes)
  807.             {
  808.                 State->PitchLFOStartCountdown = PitchDisplacementStartPoint;
  809.             }
  810.          else
  811.             {
  812.                 State->PitchLFOStartCountdown = -1;
  813.             }
  814.     }
  815.  
  816.  
  817. /* generate one sequence of samples */
  818. void                                    WaveTableGenSamples(WaveTableStateRec* State,
  819.                                                 long SampleCount, largefixedsigned* RawBuffer)
  820.     {
  821.         CheckPtrExistence(State);
  822.         CheckValidWaveTableState(State);
  823.  
  824.         if (State->PreStartCountdown <= 0)
  825.             {
  826.                 (*State->WaveTableGenSamples)(State,SampleCount,RawBuffer);
  827.             }
  828.     }
  829.  
  830.  
  831. /* find out if the wave table oscillator has finished */
  832. MyBoolean                            WaveTableIsItFinished(WaveTableStateRec* State)
  833.     {
  834.         CheckPtrExistence(State);
  835.         CheckValidWaveTableState(State);
  836.  
  837.         /* we are finished when one of the following conditions is met: */
  838.         /*  - output volume is zero AND loudness envelope is finished */
  839.         /*  - we are not generating any signal */
  840.         if (!State->WaveTableWasDefined)
  841.             {
  842.                 return True;
  843.             }
  844.         if (IsEnvelopeAtEnd(State->WaveTableLoudnessEnvelope))
  845.             {
  846.                 if (State->Template.StereoPlayback == eSampleStereo)
  847.                     {
  848.                         if ((State->LeftLoudness == 0) && (State->RightLoudness == 0))
  849.                             {
  850.                                 return True;
  851.                             }
  852.                     }
  853.                  else
  854.                     {
  855.                         if (State->OverallLoudness == 0)
  856.                             {
  857.                                 return True;
  858.                             }
  859.                     }
  860.             }
  861.         return IsEnvelopeAtEnd(State->WaveTableLoudnessEnvelope);
  862.     }
  863.  
  864.  
  865. static void                        Wave_Mono_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
  866.                                                 long SampleCount, largefixedsigned* RawBuffer)
  867.     {
  868.         LongLongRec                    LocalWaveTableSamplePosition;
  869.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  870.         unsigned long                LocalSamplePositionMask;
  871.         signed char*                WaveData;
  872.         FastFixedType                LocalOverallLoudness;
  873.  
  874.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  875.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  876.             "Wave_Mono_8BitIn_NoTime_NoWave:  wave index out of range"));
  877.         LocalOverallLoudness = State->OverallLoudness;
  878.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  879.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  880.         LocalSamplePositionMask = State->FramesPerTable - 1;
  881.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  882.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  883.             State->WaveTableIndex)]));
  884.         WaveData = (signed char*)(State->WaveTableMatrix[
  885.             FastFixed2Int(State->WaveTableIndex)]);
  886.  
  887.         while (SampleCount > 0)
  888.             {
  889.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalOverallLoudness,
  890.                     WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
  891.                     & LocalSamplePositionMask]);
  892.                 LongLongAdd(&LocalWaveTableSamplePosition,
  893.                     &LocalWaveTableSamplePositionDifferential);
  894.                 SampleCount -= 1;
  895.             }
  896.  
  897.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  898.     }
  899.  
  900.  
  901. static void                        Wave_Stereo_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
  902.                                                 long SampleCount, largefixedsigned* RawBuffer)
  903.     {
  904.         LongLongRec                    LocalWaveTableSamplePosition;
  905.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  906.         unsigned long                LocalSamplePositionMask;
  907.         signed char*                WaveData;
  908.         FastFixedType                LocalLeftLoudness;
  909.         FastFixedType                LocalRightLoudness;
  910.  
  911.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  912.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  913.             "Wave_Stereo_8BitIn_NoTime_NoWave:  wave index out of range"));
  914.         LocalLeftLoudness = State->LeftLoudness;
  915.         LocalRightLoudness = State->RightLoudness;
  916.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  917.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  918.         LocalSamplePositionMask = State->FramesPerTable - 1;
  919.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  920.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  921.             State->WaveTableIndex)]));
  922.         WaveData = (signed char*)(State->WaveTableMatrix[
  923.             FastFixed2Int(State->WaveTableIndex)]);
  924.  
  925.         while (SampleCount > 0)
  926.             {
  927.                 signed long                    SamplePoint;
  928.  
  929.                 SamplePoint = WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
  930.                     & LocalSamplePositionMask];
  931.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalLeftLoudness,SamplePoint);
  932.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalRightLoudness,SamplePoint);
  933.                 LongLongAdd(&LocalWaveTableSamplePosition,
  934.                     &LocalWaveTableSamplePositionDifferential);
  935.                 SampleCount -= 1;
  936.             }
  937.  
  938.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  939.     }
  940.  
  941.  
  942. static void                        Wave_Mono_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
  943.                                                 long SampleCount, largefixedsigned* RawBuffer)
  944.     {
  945.         LongLongRec                    LocalWaveTableSamplePosition;
  946.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  947.         unsigned long                LocalSamplePositionMask;
  948.         signed short*                WaveData;
  949.         FastFixedType                LocalOverallLoudness;
  950.  
  951.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  952.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  953.             "Wave_Mono_16BitIn_NoTime_NoWave:  wave index out of range"));
  954.         LocalOverallLoudness = State->OverallLoudness;
  955.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  956.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  957.         LocalSamplePositionMask = State->FramesPerTable - 1;
  958.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  959.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  960.             State->WaveTableIndex)]));
  961.         WaveData = (signed short*)(State->WaveTableMatrix[
  962.             FastFixed2Int(State->WaveTableIndex)]);
  963.  
  964.         while (SampleCount > 0)
  965.             {
  966.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
  967.                     WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
  968.                     & LocalSamplePositionMask]);
  969.                 LongLongAdd(&LocalWaveTableSamplePosition,
  970.                     &LocalWaveTableSamplePositionDifferential);
  971.                 SampleCount -= 1;
  972.             }
  973.  
  974.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  975.     }
  976.  
  977.  
  978. static void                        Wave_Stereo_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
  979.                                                 long SampleCount, largefixedsigned* RawBuffer)
  980.     {
  981.         LongLongRec                    LocalWaveTableSamplePosition;
  982.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  983.         unsigned long                LocalSamplePositionMask;
  984.         signed short*                WaveData;
  985.         FastFixedType                LocalLeftLoudness;
  986.         FastFixedType                LocalRightLoudness;
  987.  
  988.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  989.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  990.             "Wave_Stereo_16BitIn_NoTime_NoWave:  wave index out of range"));
  991.         LocalLeftLoudness = State->LeftLoudness;
  992.         LocalRightLoudness = State->RightLoudness;
  993.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  994.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  995.         LocalSamplePositionMask = State->FramesPerTable - 1;
  996.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  997.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  998.             State->WaveTableIndex)]));
  999.         WaveData = (signed short*)(State->WaveTableMatrix[
  1000.             FastFixed2Int(State->WaveTableIndex)]);
  1001.  
  1002.         while (SampleCount > 0)
  1003.             {
  1004.                 signed long                    SamplePoint;
  1005.  
  1006.                 SamplePoint = WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
  1007.                     & LocalSamplePositionMask];
  1008.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,SamplePoint);
  1009.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,SamplePoint);
  1010.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1011.                     &LocalWaveTableSamplePositionDifferential);
  1012.                 SampleCount -= 1;
  1013.             }
  1014.  
  1015.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1016.     }
  1017.  
  1018.  
  1019. static void                        Wave_Mono_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
  1020.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1021.     {
  1022.         LongLongRec                    LocalWaveTableSamplePosition;
  1023.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1024.         unsigned long                LocalSamplePositionMask;
  1025.         signed char*                WaveData;
  1026.         FastFixedType                LocalOverallLoudness;
  1027.  
  1028.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1029.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1030.             "Wave_Mono_8BitIn_YesTime_NoWave:  wave index out of range"));
  1031.         LocalOverallLoudness = State->OverallLoudness;
  1032.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1033.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1034.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1035.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1036.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1037.             State->WaveTableIndex)]));
  1038.         WaveData = (signed char*)(State->WaveTableMatrix[
  1039.             FastFixed2Int(State->WaveTableIndex)]);
  1040.  
  1041.         while (SampleCount > 0)
  1042.             {
  1043.                 FastFixedType                LeftWeight;
  1044.                 long                                ArraySubscript;
  1045.                 signed long                    LeftValue;
  1046.                 signed long                    RightValue;
  1047.  
  1048.                 /* naive anti-aliasing worked as follows: */
  1049.                 /*  L = left sample, R = right sample, F = fractional portion of index */
  1050.                 /*  S = L(1-F) + RF */
  1051.                 /*  Craig Peeper suggested the following optimization: */
  1052.                 /*  L(1-F)+RF ==> L-LF+RF ==> L+RF-LF ==> L+F(R-L) */
  1053.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1054.                     >> (32 - FASTFIXEDPRECISION);
  1055.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1056.                     & LocalSamplePositionMask;
  1057.                 /* L+F(R-L) */
  1058.                 LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
  1059.                 RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1060.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
  1061.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1062.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1063.                     &LocalWaveTableSamplePositionDifferential);
  1064.                 SampleCount -= 1;
  1065.             }
  1066.  
  1067.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1068.     }
  1069.  
  1070.  
  1071. static void                        Wave_Stereo_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
  1072.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1073.     {
  1074.         LongLongRec                    LocalWaveTableSamplePosition;
  1075.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1076.         unsigned long                LocalSamplePositionMask;
  1077.         signed char*                WaveData;
  1078.         FastFixedType                LocalLeftLoudness;
  1079.         FastFixedType                LocalRightLoudness;
  1080.  
  1081.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1082.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1083.             "Wave_Stereo_8BitIn_YesTime_NoWave:  wave index out of range"));
  1084.         LocalLeftLoudness = State->LeftLoudness;
  1085.         LocalRightLoudness = State->RightLoudness;
  1086.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1087.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1088.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1089.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1090.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1091.             State->WaveTableIndex)]));
  1092.         WaveData = (signed char*)(State->WaveTableMatrix[
  1093.             FastFixed2Int(State->WaveTableIndex)]);
  1094.  
  1095.         while (SampleCount > 0)
  1096.             {
  1097.                 FastFixedType                LeftWeight;
  1098.                 long                                ArraySubscript;
  1099.                 signed long                    LeftValue;
  1100.                 signed long                    RightValue;
  1101.                 signed long                    CombinedValue;
  1102.  
  1103.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1104.                     >> (32 - FASTFIXEDPRECISION);
  1105.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1106.                     & LocalSamplePositionMask;
  1107.                 /* L+F(R-L) */
  1108.                 LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
  1109.                 RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1110.                 CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1111.                 /* Oh, Please Mr. Compiler, LeftValue and RightValue are dead now!!! */
  1112.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
  1113.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
  1114.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1115.                     &LocalWaveTableSamplePositionDifferential);
  1116.                 SampleCount -= 1;
  1117.             }
  1118.  
  1119.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1120.     }
  1121.  
  1122.  
  1123. static void                        Wave_Mono_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
  1124.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1125.     {
  1126.         LongLongRec                    LocalWaveTableSamplePosition;
  1127.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1128.         unsigned long                LocalSamplePositionMask;
  1129.         signed short*                WaveData;
  1130.         FastFixedType                LocalOverallLoudness;
  1131.  
  1132.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1133.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1134.             "Wave_Mono_16BitIn_YesTime_NoWave:  wave index out of range"));
  1135.         LocalOverallLoudness = State->OverallLoudness;
  1136.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1137.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1138.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1139.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1140.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1141.             State->WaveTableIndex)]));
  1142.         WaveData = (signed short*)(State->WaveTableMatrix[
  1143.             FastFixed2Int(State->WaveTableIndex)]);
  1144.  
  1145.         while (SampleCount > 0)
  1146.             {
  1147.                 FastFixedType                LeftWeight;
  1148.                 long                                ArraySubscript;
  1149.                 signed long                    LeftValue;
  1150.                 signed long                    RightValue;
  1151.  
  1152.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1153.                     >> (32 - FASTFIXEDPRECISION);
  1154.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1155.                     & LocalSamplePositionMask;
  1156.                 /* L+F(R-L) */
  1157.                 LeftValue = WaveData[ArraySubscript];
  1158.                 RightValue = WaveData[ArraySubscript + 1];
  1159.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
  1160.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1161.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1162.                     &LocalWaveTableSamplePositionDifferential);
  1163.                 SampleCount -= 1;
  1164.             }
  1165.  
  1166.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1167.     }
  1168.  
  1169.  
  1170. static void                        Wave_Stereo_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
  1171.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1172.     {
  1173.         LongLongRec                    LocalWaveTableSamplePosition;
  1174.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1175.         unsigned long                LocalSamplePositionMask;
  1176.         signed short*                WaveData;
  1177.         FastFixedType                LocalLeftLoudness;
  1178.         FastFixedType                LocalRightLoudness;
  1179.  
  1180.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1181.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1182.             "Wave_Stereo_16BitIn_YesTime_NoWave:  wave index out of range"));
  1183.         LocalLeftLoudness = State->LeftLoudness;
  1184.         LocalRightLoudness = State->RightLoudness;
  1185.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1186.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1187.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1188.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1189.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1190.             State->WaveTableIndex)]));
  1191.         WaveData = (signed short*)(State->WaveTableMatrix[
  1192.             FastFixed2Int(State->WaveTableIndex)]);
  1193.  
  1194.         while (SampleCount > 0)
  1195.             {
  1196.                 FastFixedType                LeftWeight;
  1197.                 long                                ArraySubscript;
  1198.                 signed long                    LeftValue;
  1199.                 signed long                    RightValue;
  1200.                 signed long                    CombinedValue;
  1201.  
  1202.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1203.                     >> (32 - FASTFIXEDPRECISION);
  1204.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1205.                     & LocalSamplePositionMask;
  1206.                 /* L+F(R-L) */
  1207.                 LeftValue = WaveData[ArraySubscript];
  1208.                 RightValue = WaveData[ArraySubscript + 1];
  1209.                 CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1210.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
  1211.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
  1212.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1213.                     &LocalWaveTableSamplePositionDifferential);
  1214.                 SampleCount -= 1;
  1215.             }
  1216.  
  1217.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1218.     }
  1219.  
  1220.  
  1221. static void                        Wave_Mono_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
  1222.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1223.     {
  1224.         LongLongRec                    LocalWaveTableSamplePosition;
  1225.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1226.         unsigned long                LocalSamplePositionMask;
  1227.         signed char*                WaveData0;
  1228.         signed char*                WaveData1;
  1229.         FastFixedType                Wave0Weight;
  1230.         FastFixedType                LocalOverallLoudness;
  1231.  
  1232.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1233.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1234.             "Wave_Mono_8BitIn_YesTime_YesWave:  wave index out of range"));
  1235.         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  1236.             {
  1237.                 /* this is done in case the wave table index is at the maximum, in which */
  1238.                 /* case there is no table+1 to interpolate with. */
  1239.                 Wave_Mono_8BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
  1240.                 return;
  1241.             }
  1242.         LocalOverallLoudness = State->OverallLoudness;
  1243.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1244.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1245.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1246.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1247.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1248.             State->WaveTableIndex)]));
  1249.         WaveData0 = (signed char*)(State->WaveTableMatrix[
  1250.             FastFixed2Int(State->WaveTableIndex)]);
  1251.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1252.             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1253.             State->WaveTableIndex) + 1]));
  1254.         WaveData1 = (signed char*)(State->WaveTableMatrix[
  1255.             FastFixed2Int(State->WaveTableIndex) + 1]);
  1256.         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  1257.  
  1258.         while (SampleCount > 0)
  1259.             {
  1260.                 FastFixedType                LeftWeight;
  1261.                 long                                ArraySubscript;
  1262.                 signed long                    Left0Value;
  1263.                 signed long                    Right0Value;
  1264.                 signed long                    Left1Value;
  1265.                 signed long                    Right1Value;
  1266.                 FastFixedType                Wave0Temp;
  1267.  
  1268.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1269.                     >> (32 - FASTFIXEDPRECISION);
  1270.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1271.                     & LocalSamplePositionMask;
  1272.                 /* L+F(R-L) -- applied twice */
  1273.                 Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
  1274.                 Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
  1275.                 Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
  1276.                 Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
  1277.                 Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1278.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
  1279.                     Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
  1280.                     - Left1Value)) >> 15) - Wave0Temp)) >> 15));
  1281.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1282.                     &LocalWaveTableSamplePositionDifferential);
  1283.                 SampleCount -= 1;
  1284.             }
  1285.  
  1286.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1287.     }
  1288.  
  1289.  
  1290. static void                        Wave_Stereo_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
  1291.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1292.     {
  1293.         LongLongRec                    LocalWaveTableSamplePosition;
  1294.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1295.         unsigned long                LocalSamplePositionMask;
  1296.         signed char*                WaveData0;
  1297.         signed char*                WaveData1;
  1298.         FastFixedType                Wave0Weight;
  1299.         FastFixedType                LocalLeftLoudness;
  1300.         FastFixedType                LocalRightLoudness;
  1301.  
  1302.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1303.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1304.             "Wave_Stereo_8BitIn_YesTime_YesWave:  wave index out of range"));
  1305.         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  1306.             {
  1307.                 /* this is done in case the wave table index is at the maximum, in which */
  1308.                 /* case there is no table+1 to interpolate with. */
  1309.                 Wave_Stereo_8BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
  1310.                 return;
  1311.             }
  1312.         LocalLeftLoudness = State->LeftLoudness;
  1313.         LocalRightLoudness = State->RightLoudness;
  1314.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1315.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1316.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1317.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1318.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1319.             State->WaveTableIndex)]));
  1320.         WaveData0 = (signed char*)(State->WaveTableMatrix[
  1321.             FastFixed2Int(State->WaveTableIndex)]);
  1322.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1323.             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1324.             State->WaveTableIndex) + 1]));
  1325.         WaveData1 = (signed char*)(State->WaveTableMatrix[
  1326.             FastFixed2Int(State->WaveTableIndex) + 1]);
  1327.         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  1328.  
  1329.         while (SampleCount > 0)
  1330.             {
  1331.                 FastFixedType                LeftWeight;
  1332.                 long                                ArraySubscript;
  1333.                 signed long                    Left0Value;
  1334.                 signed long                    Right0Value;
  1335.                 signed long                    Left1Value;
  1336.                 signed long                    Right1Value;
  1337.                 FastFixedType                Wave0Temp;
  1338.  
  1339.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1340.                     >> (32 - FASTFIXEDPRECISION);
  1341.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1342.                     & LocalSamplePositionMask;
  1343.                 /* L+F(R-L) -- applied twice */
  1344.                 Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
  1345.                 Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
  1346.                 Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
  1347.                 Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
  1348.                 Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1349.                 Wave0Temp = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
  1350.                     - Left1Value)) >> 15) - Wave0Temp)) >> 15);
  1351.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,Wave0Temp);
  1352.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,Wave0Temp);
  1353.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1354.                     &LocalWaveTableSamplePositionDifferential);
  1355.                 SampleCount -= 1;
  1356.             }
  1357.  
  1358.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1359.     }
  1360.  
  1361.  
  1362. static void                        Wave_Mono_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
  1363.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1364.     {
  1365.         LongLongRec                    LocalWaveTableSamplePosition;
  1366.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1367.         unsigned long                LocalSamplePositionMask;
  1368.         signed short*                WaveData0;
  1369.         signed short*                WaveData1;
  1370.         FastFixedType                Wave0Weight;
  1371.         FastFixedType                LocalOverallLoudness;
  1372.  
  1373.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1374.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1375.             "Wave_Mono_16BitIn_YesTime_YesWave:  wave index out of range"));
  1376.         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  1377.             {
  1378.                 /* this is done in case the wave table index is at the maximum, in which */
  1379.                 /* case there is no table+1 to interpolate with. */
  1380.                 Wave_Mono_16BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
  1381.                 return;
  1382.             }
  1383.         LocalOverallLoudness = State->OverallLoudness;
  1384.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1385.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1386.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1387.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1388.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1389.             State->WaveTableIndex)]));
  1390.         WaveData0 = (signed short*)(State->WaveTableMatrix[
  1391.             FastFixed2Int(State->WaveTableIndex)]);
  1392.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1393.             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1394.             State->WaveTableIndex) + 1]));
  1395.         WaveData1 = (signed short*)(State->WaveTableMatrix[
  1396.             FastFixed2Int(State->WaveTableIndex) + 1]);
  1397.         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  1398.  
  1399.         while (SampleCount > 0)
  1400.             {
  1401.                 FastFixedType                LeftWeight;
  1402.                 long                                ArraySubscript;
  1403.                 signed long                    Left0Value;
  1404.                 signed long                    Right0Value;
  1405.                 signed long                    Left1Value;
  1406.                 signed long                    Right1Value;
  1407.                 FastFixedType                Wave0Temp;
  1408.  
  1409.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1410.                     >> (32 - FASTFIXEDPRECISION);
  1411.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1412.                     & LocalSamplePositionMask;
  1413.                 /* L+F(R-L) -- applied twice */
  1414.                 Left0Value = WaveData0[ArraySubscript];
  1415.                 Right0Value = WaveData0[ArraySubscript + 1];
  1416.                 Left1Value = WaveData1[ArraySubscript];
  1417.                 Right1Value = WaveData1[ArraySubscript + 1];
  1418.                 Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1419.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
  1420.                     Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
  1421.                     - Left1Value)) >> 15) - Wave0Temp)) >> 15));
  1422.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1423.                     &LocalWaveTableSamplePositionDifferential);
  1424.                 SampleCount -= 1;
  1425.             }
  1426.  
  1427.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1428.     }
  1429.  
  1430.  
  1431. static void                        Wave_Stereo_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
  1432.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1433.     {
  1434.         LongLongRec                    LocalWaveTableSamplePosition;
  1435.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1436.         unsigned long                LocalSamplePositionMask;
  1437.         signed short*                WaveData0;
  1438.         signed short*                WaveData1;
  1439.         FastFixedType                Wave0Weight;
  1440.         FastFixedType                LocalLeftLoudness;
  1441.         FastFixedType                LocalRightLoudness;
  1442.  
  1443.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1444.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1445.             "Wave_Stereo_16BitIn_YesTime_YesWave:  wave index out of range"));
  1446.         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  1447.             {
  1448.                 /* this is done in case the wave table index is at the maximum, in which */
  1449.                 /* case there is no table+1 to interpolate with. */
  1450.                 Wave_Stereo_16BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
  1451.                 return;
  1452.             }
  1453.         LocalLeftLoudness = State->LeftLoudness;
  1454.         LocalRightLoudness = State->RightLoudness;
  1455.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1456.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1457.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1458.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1459.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1460.             State->WaveTableIndex)]));
  1461.         WaveData0 = (signed short*)(State->WaveTableMatrix[
  1462.             FastFixed2Int(State->WaveTableIndex)]);
  1463.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1464.             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1465.             State->WaveTableIndex) + 1]));
  1466.         WaveData1 = (signed short*)(State->WaveTableMatrix[
  1467.             FastFixed2Int(State->WaveTableIndex) + 1]);
  1468.         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  1469.  
  1470.         while (SampleCount > 0)
  1471.             {
  1472.                 FastFixedType                LeftWeight;
  1473.                 long                                ArraySubscript;
  1474.                 signed long                    Left0Value;
  1475.                 signed long                    Right0Value;
  1476.                 signed long                    Left1Value;
  1477.                 signed long                    Right1Value;
  1478.                 FastFixedType                Wave0Temp;
  1479.  
  1480.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1481.                     >> (32 - FASTFIXEDPRECISION);
  1482.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1483.                     & LocalSamplePositionMask;
  1484.                 /* L+F(R-L) -- applied twice */
  1485.                 Left0Value = WaveData0[ArraySubscript];
  1486.                 Right0Value = WaveData0[ArraySubscript + 1];
  1487.                 Left1Value = WaveData1[ArraySubscript];
  1488.                 Right1Value = WaveData1[ArraySubscript + 1];
  1489.                 Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1490.                 Wave0Temp = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
  1491.                     * (Right1Value - Left1Value)) >> 15) - Wave0Temp)) >> 15);
  1492.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,Wave0Temp);
  1493.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,Wave0Temp);
  1494.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1495.                     &LocalWaveTableSamplePositionDifferential);
  1496.                 SampleCount -= 1;
  1497.             }
  1498.  
  1499.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1500.     }
  1501.  
  1502.  
  1503. static void                        Wave_NoOutput(WaveTableStateRec* State,
  1504.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1505.     {
  1506.     }
  1507.